package lsf.aHttp

import Strs
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.Environment
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import com.koushikdutta.async.http.body.JSONObjectBody
import com.koushikdutta.async.http.body.MultipartFormDataBody
import com.koushikdutta.async.http.body.StringBody
import com.koushikdutta.async.http.body.UrlEncodedFormBody
import com.koushikdutta.async.http.server.AsyncHttpServer
import kotlinx.android.synthetic.main.server.*
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.net.URLDecoder


val sd = Environment.getExternalStorageDirectory()!!.absolutePath

private var server0: AsyncHttpServer? = null

private var txt: String = ""

private fun toIp(j: Int): String {
    var j = j
    var s = (j and 0xff).toString()
    for (i in 0..2) {
        j = j shr 8
        s += "." + (j and 0xff)
    }
    return s
}

class ServerActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.server)

        dir.setText(sd)

        text.setText(txt)
        text.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {}
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                txt = text.text.toString()
            }
        })

        val wifiManager = applicationContext?.getSystemService(Context.WIFI_SERVICE) as WifiManager
        ip?.text = if (wifiManager.isWifiEnabled) "IP：" +
                toIp(wifiManager.connectionInfo.ipAddress) else "WIFI未开启"

        cmd.text = if (server0 == null) "启动" else "停止"
        cmd.setOnClickListener {
            if (server0 != null) {
                server0?.stop()
                server0 = null
                cmd.text = "启动"
                toast("server已停止")
            } else {
                startServer()
                cmd.text = "停止"
                toast("server已启动")
            }
        }
    }

    private fun startServer() {
        val server = AsyncHttpServer()
        server0 = server

        server.setErrorCallback {
            toast("出现了一个错误：" + it.message)
        }

        server.get("/") { _, response ->
            val input = resources.assets.open("index.html")
            response.setContentType("text/html;charset=utf-8")
            response.sendStream(input, input.available().toLong())
        }

        //发送文本
        server.get("/r") { _, response ->
            response.setContentType("text/plain;charset=utf-8")
            response.send(txt)
        }

        //发送文件
        server.get("/d(?:/.*)?") { request, response ->
            var s = ""
            Strs.split1(request.path).forEach { s += "/" + URLDecoder.decode(it, "utf-8") }

            s = sd + s

            val f = File(s)
            if (f.exists()) {
                if (f.isFile) {
                    if (AsyncHttpServer.tryGetContentType(s) == null)
                        response.setContentType("application/octet-stream")

                    response.sendFile(f)
                    toast(s + "已被下载")

                } else {
                    val o = JSONObject()
                    f.listFiles()?.forEach {
                        val o1 = JSONObject()
                        if (it.isFile) o1.put("size", it.length())
                        o.put(it.name, o1)
                    }
                    response.send(o)
                }
            } else {
                response.code(404)
                response.end()
            }

        }

        server.post("/s") { request, response ->

            when (val body = request.body) {
                is UrlEncodedFormBody -> {
                    var s = ""
                    for (pair in body.get()) {
                        s += pair?.name + pair?.value
                    }
                    toast(s)
                }
                is JSONObjectBody -> toast(body.get().toString())
                is StringBody -> {
                    //bug，只支持ascii
                    val s = body.get()
                    toast(s)
                }

                // 文件上传
                is MultipartFormDataBody -> {
                    val map = HashMap<String, OutputStream>()

                    body.setMultipartCallback { part ->
                        val fn = (part.filename as java.lang.String).replaceAll("[^-\\w. ]", "")

                        toast("$sd/$fn")

                        if (!map.contains(fn)) map[fn] = FileOutputStream("$sd/$fn")

                        if (part.isFile) body.setDataCallback { _, bb ->
                            val os = map[fn]
                            os?.write(bb.allByteArray)
                            bb.recycle()
                        }
                    }
                    request.setEndCallback {
                        if (it != null) toast(it.message)
                        response.end()
                        map.values.forEach {
                            it.flush()
                            it.close()
                        }
                        toast("上传完成")
                        map.keys.forEach {
                            //安装
                            if ((it as java.lang.String).endsWith(".apk"))
                                install("$sd/$it")
                        }
                    }
                }
            }

        }

        server.listen(8888)
    }


    private fun toast(s: String?) = runOnUiThread {
        Toast.makeText(this, s, Toast.LENGTH_LONG).show()
    }

    private fun install(s: String) {
        startActivity(Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(File(s)),
                "application/vnd.android.package-archive"))
    }

}



